Skip to content

tr: add codspeed benchmark#12189

Open
parasol-aser wants to merge 2 commits into
uutils:mainfrom
parasol-aser:tr/codspeed-bench
Open

tr: add codspeed benchmark#12189
parasol-aser wants to merge 2 commits into
uutils:mainfrom
parasol-aser:tr/codspeed-bench

Conversation

@parasol-aser
Copy link
Copy Markdown

What

Adds a divan-based benchmark suite at src/uu/tr/benches/tr_bench.rs, registered in .github/workflows/benchmarks.yml so CodSpeed tracks it on every PR.

tr only reads stdin, so each bench redirects fd 0 to a prepared file (and fd 1 to /dev/null) around uumain, mirroring the existing src/uu/tee/benches/tee_bench.rs pattern with rustix.

The suite covers four cases at 1 / 16 / 64 MB inputs:

  • tr_ascii_range_lower_to_uppertr a-z A-Z (range translation)
  • tr_single_char_replacetr a b (single-byte SIMD path)
  • tr_multi_char_translatetr aeiou AEIOU (table-lookup path)
  • tr_delete_ascii_rangetr -d a-z (deletion path)

Why

Requested by @sylvestre in #12118 to provide regression coverage for the tr translation paths and the upcoming AVX2 ASCII-range fast path landing in that PR.

Local invocation

cargo bench -p uu_tr
# or, mirroring CI:
cargo codspeed build -p uu_tr && cargo codspeed run -p uu_tr

Notes

  • Bench code is #[cfg(unix)] because the rustix stdin/stdout redirection is unix-only; on other targets the bench compiles to an empty divan::main().
  • No production source changes — only benches/, Cargo.toml dev-deps, and the workflow matrix.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 7, 2026

GNU testsuite comparison:

Skip an intermittent issue tests/date/date-locale-hour (fails in this run but passes in the 'main' branch)
Skip an intermittent issue tests/tail/tail-n0f (fails in this run but passes in the 'main' branch)
Skipping an intermittent issue tests/cut/bounded-memory (passes in this run but fails in the 'main' branch)
Congrats! The gnu test tests/expand/bounded-memory is now passing!
Congrats! The gnu test tests/seq/seq-epipe is now passing!

Comment thread src/uu/tr/BENCHMARKING.md Outdated

`tr` performance is critical for large data processing pipelines. The implementation uses lookup tables for O(1) character operations.

## CodSpeed (CI)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove this

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 190a973 — removed the CodSpeed section.

Comment thread src/uu/tr/benches/tr_bench.rs Outdated
/// Exercises the AVX2 ASCII-range fast path on x86_64 hosts that
/// support it, and the scalar range fallback on other targets.
#[cfg(unix)]
#[divan::bench(args = [1, 16, 64])]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please test with only one value

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 190a973 — collapsed to a single 16 MB size (SIZE_MB const) across all four benches.

Adds a divan-based benchmark suite under src/uu/tr/benches/ that
codspeed can build and run, and registers uu_tr in the benchmarks
workflow matrix. Each bench redirects fd 0 to a prepared file and
fd 1 to /dev/null around uumain since tr only reads stdin.

Covers the AVX2 ASCII-range fast path, single-char replace,
multi-char table translation, and ASCII range delete, at 1/16/64 MB.
//! so the translated output does not flood the harness's terminal.
//! Both fds are restored after each iteration.

#[cfg(unix)]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why all these unix cfg ?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I kept the benchmark Unix-gated because it redirects stdin/stdout with rustix fd helpers and /dev/null, but grouped the benchmark code under one cfg(unix) module to make that clearer.

@oech3
Copy link
Copy Markdown
Contributor

oech3 commented May 15, 2026

Is this OK to merge?

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented May 15, 2026

Merging this PR will improve performance by 3.81%

⚡ 1 improved benchmark
✅ 316 untouched benchmarks
🆕 8 new benchmarks
⏩ 46 skipped benchmarks1

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Simulation sort_long_line[10000] 424.4 µs 408.8 µs +3.81%
🆕 Simulation tr_multi_char_translate N/A 33.7 ms N/A
🆕 Simulation tr_delete_ascii_range N/A 38.3 ms N/A
🆕 Simulation tr_single_char_replace N/A 5.5 ms N/A
🆕 Simulation tr_ascii_range_lower_to_upper N/A 33.8 ms N/A
🆕 Memory tr_single_char_replace N/A 35.4 KB N/A
🆕 Memory tr_multi_char_translate N/A 35.4 KB N/A
🆕 Memory tr_delete_ascii_range N/A 35.4 KB N/A
🆕 Memory tr_ascii_range_lower_to_upper N/A 116.1 KB N/A

Tip

Curious why this is faster? Comment @codspeedbot explain why this is faster on this PR, or directly use the CodSpeed MCP with your agent.


Comparing parasol-aser:tr/codspeed-bench (0d9b915) with main (28cff68)

Open in CodSpeed

Footnotes

  1. 46 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants